﻿#ifndef __SS_QUEUE_H__
#define __SS_QUEUE_H__
#include "../ssBaseDefine.h"
#include "../thread/threadLock/ssAtomic.h"

namespace StarSeeker
{

//这是一个头尾相连的环状队列，该队列可用于两个线程（一个线程只push,一个线程只pop）间的消息传递而无需加锁
template<typename T>
class ssQueue
{
public:
	struct Node_s
	{
		friend class ssQueue;
		Node_s* Next()
		{
			return pNext;
		}
	private:
		T			data;
		Node_s*		pNext;
	};

	class Iterator
	{
		friend class ssQueue;
	public:
		Iterator() :m_pNode(0)
		{
		}
		Iterator(const Iterator& i) :m_pNode(i.m_pNode)
		{
		}
		Iterator(Node_s*& p) :m_pNode(p)
		{
		}
		void operator= (const Iterator& i)
		{
			m_pNode = i.m_pNode;
		}
		void operator++ ()
		{
			if (m_pNode)
				m_pNode = m_pNode->pNext;
		}
		bool operator== (const Iterator& i)
		{
			return m_pNode == i.m_pNode;
		}
		bool operator!= (const Iterator& i)
		{
			return m_pNode != i.m_pNode;
		}
		T& operator* ()
		{
			return m_pNode->data;
		}
		T* Data()
		{
			return m_pNode ? &m_pNode->data : 0;
		}
		Node_s* Node() const
		{
			return m_pNode;
		}
		bool IsVaild() const
		{
			return m_pNode != 0;
		}
	private:
		Node_s* m_pNode;
	};

private:
	ssQueue(const ssQueue* qc){}
	void operator=(const ssQueue* qc){}
public:
	ssQueue()
	{
		m_head = 0;
		m_read = 0;
		m_write = 0;
		m_count = 0;
		m_nodeCount = 0;
	}
	~ssQueue()
	{
		Clear();
	}
	//入队
	void Push(T& t)
	{
		if (m_head==0) //空链表
		{
			m_head = new Node_s;
			m_head->pNext = new Node_s;
			m_head->pNext->pNext = m_head;
			m_read = m_head;
			m_write = m_head->pNext;
			m_count = 1;
			m_nodeCount = 2;
			m_head->data = t;
		}
		else
		{
			if (m_read==m_write->pNext) //没有空节点
			{
				Node_s* newNode = new Node_s;
				m_write->pNext = newNode;
				newNode->pNext = m_read;
				++m_nodeCount;
			}
			m_write->data = t;
			m_write = m_write->pNext;
			++m_count;
		}
	}
	//出队
	bool Pop()
	{
		if (m_read!=m_write && m_read && m_count>0)
		{
			m_read = m_read->pNext;
			--m_count;
			return true;
		}
		return false;
	}
	//返回队列的第一个对象，需要调用Pop才真正的出队，Pop之后不能再操作返回的对象因为被回收再利用了
	T* Front()
	{
		if (m_read!=m_write && m_read && m_count>0)
		{
			return &m_read->data;
		}
		return 0;
	}
	//出队并返回对象的拷贝，Front()+Pop()
	bool PopFront(T& t)
	{
		if (m_read!=m_write && m_read && m_count>0)
		{
			t = m_read->data;
			m_read = m_read->pNext;
			--m_count;
			return true;
		}
		return false;
	}
	//清空队列
	void Empty()
	{
		if (m_write)
		{
			m_read = m_write;
			m_count = 0;
		}
	}
	//释放内存
	void Clear()
	{
		if (m_head)
		{
			Node_s* tmp = 0;
			for (ulint i=0; i<m_nodeCount.Value(); ++i)
			{
				tmp = m_head;
				m_head = m_head->pNext;
				delete tmp;
			}
		}
		m_head = 0;
		m_read = 0;
		m_write = 0;
		m_count = 0;
		m_nodeCount = 0;
	}
	//是否空
	bool IsEmpty() const
	{
		return m_count==0;
	}
	//返回元素个数
	ulint Count() const
	{
		return m_count.Value();
	}
	//返回链表节点总数
	ulint TotalCount() const
	{
		return m_nodeCount.Value();
	}
	//遍历用的
	Iterator Begin()
	{
		return m_read;
	}
	Iterator End()
	{
		return m_write;
	}
private:
	Node_s*				m_head;		//链表头
	Node_s*				m_read;		//读指针
	Node_s*				m_write;	//写指针
	ssAtomic<ulint>		m_count;	//计数器
	ssAtomic<ulint>		m_nodeCount;//节点总数
};

}
#endif
